package ec.fugu.util;

import java.io.IOException;
import java.util.Hashtable;

//Views of BlackBerry APP
import com.xxx.views.XXXBlackBerry;

import net.rim.device.api.i18n.ResourceBundle;
//Resource for the i18n internationalization
import assets.res.XXXResource;
import ec.fugu.amf.AmfClient;
import ec.fugu.amf.AmfMessage;

/**
 * NetworkThread
 * 
 * This is just a Thread which the Main UI must wait for.
 * 
 * In most applications this will be a networking Thread
 * so this sample has been designed to simulate that.
 * It is created with a URL and returns a byte array.
 *
 */

public class NetworkThread extends Thread  implements XXXResource{

	private static ResourceBundle _res = ResourceBundle.getBundle(BUNDLE_ID, BUNDLE_NAME);
	private ObserverInterface _ourObserver;
    private AmfClient _client = null;
    private String _method = null;
    private Object[] _params = null;
    private AmfMessage _response;
    private boolean _stopRequest = false;
    private boolean _needAuth = false;
//    private long _startTime=0;
//    private long _finishTime=0;
    private int _timeout=3000;
    
    /**
     * Create a networkThread
     * @param client AmfClient to use in the Thread
     * @param method Remote method to be invoked
     * @param params Params of the Remote Method
     * @param timeout Timeout of the request
     * @param observer 
     */
    public NetworkThread(AmfClient client, String method, Object[] params, int timeout,ObserverInterface observer) {
        super();
        _client = client;
        _ourObserver = observer;
        _method = method;
        _params = params;
        _timeout = timeout;
    }

    public NetworkThread(AmfClient client, String method, Object[] params, int timeout,ObserverInterface observer, boolean needAuth) {
        super();
        _client = client;
        _ourObserver = observer;
        _method = method;
        _params = params;
        _timeout = timeout;
        _needAuth = needAuth;
    }

    /**
     * stop is called if the processing should not continue.
     */
    public void stop() {
        // Tell our observer
        observerError(ObserverInterface.CANCELLED, _res.getString(CANCELED));
        _stopRequest = true; // Will no longer tell Observer anything
        this.interrupt(); // Give our Thread a kick
    }

    private void observerStatusUpdate(final int status, final String statusString) {
        if ( !_stopRequest ) {
            _ourObserver.processStatusUpdate(status, statusString);
        }
    }

    private void observerError(int errorCode, String errorMessage) {
        if ( !_stopRequest ) {
            _ourObserver.processError(errorCode, errorMessage);
        }
    }

    private void observerResponse(AmfMessage reply) {
        if ( !_stopRequest ) {
            _ourObserver.processResponse(reply);
        }
    }

    /**
     * Process the long running or blocking operation in this Thread
     * Update the Observer as required using
     * - processStatus, whenever desired
     * and then one of:
     * - processError, if there was a problem
     * - processResponse, if the data was obtained OK
     */
    public void run () {
      boolean willFail = false; // false - will finshed OK, true - will fail!
//        _startTime = System.currentTimeMillis();
//        _finishTime = _startTime + _timeout;
      String errmes = "";
      observerStatusUpdate(1, "Started"); // Tell user we have started
      try {
        if(_timeout<0)
           throw new IOException("Timeout cannot be less than zero");
           _client.resetRequest();
           //XXXBlackBerry.hasCredentials() returns a true if credentials were entered in the GUI APP  
           //XXXBlackBerry.getCredentials() returns a Hashtable with the credentials from the blackberry app gui
           if(_needAuth && XXXBlackBerry.hasCredentials()){
             Hashtable credentials = XXXBlackBerry.getCredentials();
             _client.setCredentials(credentials.get("username").toString(), credentials.get("password").toString());
           } else if(_needAuth && !XXXBlackBerry.hasCredentials()){
             throw new IOException(_res.getString(MISSINGCREDENTIAL));
           }
        _client.sendRequest(_method, _params);
        _response=_client.getResponse();
	      observerStatusUpdate(100, "Finished"); // Tell Observer we have finished
      } catch (IOException e) {
			System.err.println("NetworkThread-run IOException: " + e.getMessage());
			errmes = e.getMessage();
			e.printStackTrace();
			willFail = true;
		}
//        _finishTime = System.currentTimeMillis();
        //  Did we finish OK or badly
        if ( willFail ) {
            observerError(ObserverInterface.ERROR, errmes);
        } else {
            observerResponse(_response);
        }

        // Make sure we do nothing else
        _stopRequest = true;
        _ourObserver = null;
    }
}